﻿// <copyright file="ShelveSetControl.xaml.cs" company="Soumya Chattopadhyay">
// Copyright (c) 2010 All Right Reserved
// </copyright>
// <disclaimer> This software is intented for educational purposes only and not for 
// commerical or prodution use. The software is provided "as is", without warranty 
// of any kind, express or implied, including but not limited to the warranties of 
// merchantability, fitness for a particular purpose and noninfringement. In no event 
// shall the author(s) or copyright holder(s) be liable for any claim, damages or other 
// liability, whether in an action of contract, tort or otherwise, arising from, out of 
// or in connection with the software or the use or other dealings in the software.
// </disclaimer>

namespace My.CodePlex.TFSExplorer
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.IO;
    using System.Threading;
    using System.Windows.Controls;
    using Microsoft.TeamFoundation.VersionControl.Client;
    using My.CodePlex.TFSExplorer.Resources;
    using My.CodePlex.TFSExplorer.TeamFoundation;

    /// <summary>
    /// Interaction logic for ShelveSetControl.xaml
    /// </summary>
    public partial class ShelveSetControl : UserControl, IExplorerControl
    {
        #region Fields

        /// <summary>
        /// The version control server
        /// </summary>
        private VersionControlServer versionControlServer;

        /// <summary>
        /// Thread that populates the shelveset
        /// </summary>
        private Thread populateShelvesetThread;

        /// <summary>
        /// The current displayed user
        /// </summary>
        private string displayedUser;

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the ShelveSetControl class
        /// </summary>
        public ShelveSetControl()
        {
            InitializeComponent();

            this.ControlName = Resource.ShelveSetControlName;
            this.Header = Resource.ShelvesetTabItemHeader;

            this.ShelveSetView.SelectionChanged += this.ShelveSetViewSelectionChanged;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets  the control name
        /// </summary>
        public string ControlName { get; set; }

        /// <summary>
        /// Gets or sets the control tab item header
        /// </summary>
        public string Header { get; set; }

        /// <summary>
        /// Gets or sets the TFS context
        /// </summary>
        public TeamFoundationContext TeamFoundationContext { get; set; }

        #endregion

        #region Public Methods

        /// <summary>
        /// Populate the control with the current users shelveset
        /// </summary>
        /// <param name="tfsContext">The TFS context</param>
        public void Populate(TeamFoundationContext tfsContext)
        {
            this.TeamFoundationContext = tfsContext;

            this.versionControlServer = TeamFoundationContext.VersionControlServer;
            this.displayedUser = TeamFoundationContext.CurrentDisplayUser;

            // Set up the thread to populate the source tree view
            this.populateShelvesetThread = new Thread(this.PopulateShelveSetView);
            this.populateShelvesetThread.SetApartmentState(ApartmentState.STA);
            this.populateShelvesetThread.Start(TeamFoundationContext.CurrentProject.ServerItem);
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Populate the shelveset listview
        /// </summary>
        /// <param name="data">The name of the topmost folder</param>
        private void PopulateShelveSetView(object data)
        {
            Shelveset[] shelvesetArray = this.versionControlServer.QueryShelvesets(string.Empty, TeamFoundationContext.CurrentDisplayUser);

            ObservableCollection<ShelvesetItem> obsCollection = new ObservableCollection<ShelvesetItem>();

            foreach (Shelveset shelveset in shelvesetArray)
            {
                ShelvesetItem fileItem = new ShelvesetItem();
                fileItem.Name = shelveset.Name;
                fileItem.CreationDate = shelveset.CreationDate.ToShortDateString() + " " + shelveset.CreationDate.ToLongTimeString();
                fileItem.Comment = shelveset.Comment;
                fileItem.Tag = shelveset;
                obsCollection.Add(fileItem);
            }

            this.ShelveSetView.Dispatcher.BeginInvoke((Action)(() =>
            {
                this.ShelveSetView.ItemsSource = obsCollection;
            }));
        }

        /// <summary>
        /// When the shelveset selection changes; we'll display the shelveset details
        /// </summary>
        /// <param name="sender">The sender object</param>
        /// <param name="e">The event arguments</param>
        private void ShelveSetViewSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            this.ShelveSetDetailView.Dispatcher.BeginInvoke((Action)(() =>
            {
                if (this.ShelveSetView.SelectedItem != null)
                {
                    ObservableCollection<PendingChangeItem> obsCollection = new ObservableCollection<PendingChangeItem>();

                    ShelvesetItem sv = (ShelvesetItem)this.ShelveSetView.SelectedItem;
                    PendingSet[] pendingSetArray = versionControlServer.QueryShelvedChanges((Shelveset)sv.Tag);

                    foreach (PendingSet pendingSet in pendingSetArray)
                    {
                        foreach (PendingChange pendingChange in pendingSet.PendingChanges)
                        {
                            PendingChangeItem fileItem = new PendingChangeItem();
                            fileItem.FileName = Path.GetFileName(pendingChange.ServerItem);
                            fileItem.ServerItem = pendingChange.ServerItem;

                            fileItem.ImgSource = FileIconRepository.GetFileIconImage(Path.GetExtension(fileItem.FileName)).ToImageSource();
                            fileItem.ChangeTypeName = pendingChange.ChangeTypeName;
                            fileItem.CreationDate = pendingChange.CreationDate.ToShortDateString() + " " + pendingChange.CreationDate.ToLongTimeString();
                            fileItem.LocalItem = pendingChange.LocalItem;

                            obsCollection.Add(fileItem);
                        }
                    }

                    this.ShelveSetDetailView.ItemsSource = obsCollection;
                }
            }));
        }

        #endregion

        /// <summary>
        /// Refresh the shelveset view
        /// </summary>
        /// <param name="sender">The sender object</param>
        /// <param name="e">The event arguments</param>
        private void RefreshClick(object sender, System.Windows.RoutedEventArgs e)
        {
            // Refresh the shelve set view
            this.Populate(this.TeamFoundationContext);
        }

        /// <summary>
        /// Delete a shelveset
        /// </summary>
        /// <param name="sender">The sender object</param>
        /// <param name="e">The event arguments</param>
        private void DeleteClick(object sender, System.Windows.RoutedEventArgs e)
        {
            if (this.ShelveSetView.SelectedItem != null)
            {
                ShelvesetItem sv = (ShelvesetItem)this.ShelveSetView.SelectedItem;
                TeamFoundationContext.VersionControlServer.DeleteShelveset(sv.Name, TeamFoundationContext.CurrentDisplayUser);
            }

            // Refresh the shelve set view
            this.Populate(this.TeamFoundationContext);
        }

        /// <summary>
        /// Unshelve a shelveset
        /// </summary>
        /// <param name="sender">The sender object</param>
        /// <param name="e">The event arguments</param>
        private void UnShelveClick(object sender, System.Windows.RoutedEventArgs e)
        {
            if (this.ShelveSetView.SelectedItem != null)
            {
                ShelvesetItem sv = (ShelvesetItem)this.ShelveSetView.SelectedItem;
                TeamFoundationContext.Workspace.Unshelve(sv.Name, TeamFoundationContext.CurrentDisplayUser);
            }
        }
    }
}
